# -*- coding:utf8 -*-
"""
用户日志配置工具
"""
from __future__ import print_function, unicode_literals, division
import logging
import logging.handlers
from logging import basicConfig, INFO, DEBUG, WARNING, ERROR
import datetime


getLogger = logging.getLogger


class LoggerConfig(object):
    """
    日志配置信息

    使用：
        1. 产生对象 LoggerConfig('server.log', type_...)
        2. 动态配置 log_config.config(to_screen=False, level=INFO)
        3. 获取文件夹中该配置模式产生的文件 log_config.find_files(days_ago=3)
    """

    MSG_FORMAT = {
        0: [
            #'%(name)-10s: %(levelname)-5s: %(asctime)s: %(message)s',  # 格式
            '[%(asctime)s][pid:%(process)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d][%(levelname)s][%(message)s]',
            r'(.*?):(.*?):(.*?):(.*)',  # 提取正则表达式
            ['name', 'level', 'time', 'msg']  # 提取出来对应字段
        ],
        1: [
            '[%(asctime)s] [%(levelname)s] [%(module)s] [%(funcName)s] [%(lineno)d] %(message)s',
            None,
            None
        ]
    }

    DATE_FORMAT = {
        0: ('%Y%m%d %H:%M:%S', r'(\d{8} \d{2}:\d{2}:\d{2})'),
        1: ('%Y-%m-%d %H:%M:%S', r'(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})')
    }

    WEEK_TYPE = 1
    DAY_TYPE = 2
    MIDNIGHT_TYPE = 3  # 每天午夜生成一个文件
    ONCE_TYPE = 4  # 每运行一次产生一个带时间的文件，要求base_path中有 {time}
    MULTI_PROCESSES = 5

    FILE_TIME_FORMAT = {
        MIDNIGHT_TYPE: ("%Y-%m-%d", r'(\d{4}-\d{2}-\d{2})'),
        ONCE_TYPE: ('%Y%m%d%H%M%S', r'\.(\d{14})\.')
    }

    def __init__(
            self,
            base_path=None,
            type_=MIDNIGHT_TYPE,
            msg_format_index=0,
            date_format_index=0):
        self.base_path = base_path
        self.type_ = type_
        self.mf_index = msg_format_index
        self.df_index = date_format_index
        self.msg_format = self.MSG_FORMAT[msg_format_index][0]
        self.date_format = None

    def config(self, to_screen=False, level=logging.DEBUG, log_count=30):
        print("Logger Config Param: ", to_screen, level, self.type_, self.base_path)
        if to_screen:
            basicConfig(
                level=level,
                format=self.msg_format,
                datefmt=self.date_format,
                filename=None,
                filemode='a+')

        elif self.type_ == self.MULTI_PROCESSES:
            multi_log_config(
                self.base_path,
                level,
                "midnight",
                1,
                self.msg_format,
                self.date_format,
                log_count)

        elif self.type_ == self.WEEK_TYPE:
            period_log_config(
                self.base_path,
                level,
                "W0",
                1,
                self.msg_format,
                self.date_format,
                log_count)

        elif self.type_ == self.MIDNIGHT_TYPE:
            period_log_config(
                self.base_path,
                level,
                "midnight",
                1,
                self.msg_format,
                self.date_format,
                log_count)

        elif self.type_ == self.DAY_TYPE:
            period_log_config(
                self.base_path,
                level,
                "D",
                1,
                self.msg_format,
                self.date_format,
                log_count)

        elif self.type_ == self.ONCE_TYPE:
            real_path = self.base_path.format(
                time=datetime.datetime.now().strftime(self.FILE_TIME_FORMAT[self.ONCE_TYPE][0]))
            log_basic_config(
                real_path,
                level,
                self.msg_format,
                self.date_format)


def log_basic_config(
        file_path=None,
        level=INFO,
        msg_format='%(name)-10s: %(levelname)-5s: %(asctime)s: %(message)s',
        date_format='%Y%m%d %H:%M:%S'):
    basicConfig(
        level=level,
        format=msg_format,
        datefmt=date_format,
        filename=file_path,
        filemode='a+'
    )


def period_log_config(
        file_basic,
        level,
        type_,
        number,
        msg_format,
        date_format,
        log_count=0):
    if file_basic:
        logging.getLogger().setLevel(logging.DEBUG)
        logger_handler = logging.handlers.TimedRotatingFileHandler(
            file_basic, type_, number, backupCount=log_count)
        logger_handler.setLevel(level)
        logger_handler.setFormatter(logging.Formatter(msg_format, date_format))

        logger_ = logging.getLogger('')
        logger_.addHandler(logger_handler)

    else:
        basicConfig(level=level, format=msg_format, datefmt=date_format)


def multi_log_config(
    file_basic,
    level,
    type_,
    number,
    msg_format,
    date_format,
    log_count=0
):
    if file_basic:
        from cloghandler import ConcurrentRotatingFileHandler
        logging.getLogger().setLevel(logging.DEBUG)
        logger_handler = ConcurrentRotatingFileHandler(
            file_basic, "a", 50 * 1024 * 1024, 5)
        logger_handler.setLevel(level)
        logger_handler.setFormatter(logging.Formatter(msg_format, date_format))

        logger_ = logging.getLogger('')
        logger_.addHandler(logger_handler)

    else:
        basicConfig(level=level, format=msg_format, datefmt=date_format)
